package com.gqzm.side.common.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gqzm.side.domain.bo.PersistenceInfo;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;
import java.util.UUID;

/**
 * @ClassName: {@link PersistenceFileUtils}
 * @description: 本地持久化工具类
 * @author: peter qin
 * @date: 2023 12 18
 * @version: 1.0
 **/
@Slf4j
@UtilityClass
public class PersistenceFileUtils {
    private static String PERSISTENCE_FILE_PATH;

    private static String OS_NAME;


    static {
        Properties props = System.getProperties();
        String userDir = props.getProperty("user.dir");
        OS_NAME = props.getProperty("os.name");
        /**
         * 持久化静态数据
         * {
         *      //盒子编码持久化,sn code
         *      "code" : "xxx",
         *      //盒子名称持久化，sn Code
         *      "name" : "name"
         *      //当前执行到哪一张图片
         *      "detect" : "file_name"
         * }
         */
        PERSISTENCE_FILE_PATH = userDir + File.separator + "persistence.json";
        //初始化持久化数据
        init();
    }


    private static void init() {
        Path path = Paths.get(PERSISTENCE_FILE_PATH);
        if (!Files.exists(path)) {
            try {
                Files.createFile(path);
                writePersistence(new PersistenceInfo(), path);
            } catch (Exception e) {
                log.error("创建持久化文件异常", e);
            }
        }
        PersistenceInfo pi = readPersistence();
        if (StringUtils.isBlank(pi.getCode())
                || StringUtils.isBlank(pi.getName())) {
            String sn = getSnCode();
            pi.setCode(sn);
            pi.setName(sn);
        }
        writePersistence(pi, path);
    }


    private static String getSnCode() {
        if (OS_NAME.toLowerCase().contains("windows")) {
            return windowsSerialNumber();
        }
        return linuxSerialNumber();
    }


    @SneakyThrows
    private static String linuxSerialNumber() {
        //运行命令获取SN值
        Process process = Runtime.getRuntime().exec("cat /sys/class/dmi/id/product_serial");
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (StringUtils.isNotBlank(line)) {
                    return line.trim();
                }
            }
        }
        return UUID.randomUUID().toString();
    }


    @SneakyThrows
    private static String windowsSerialNumber() {
        Process process = Runtime.getRuntime().exec("wmic bios get serialnumber"); // 运行命令获取SN值
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (StringUtils.isNotBlank(line)
                        && !StringUtils.equals(line.trim(), "SerialNumber")) {
                    return line.trim();
                }
            }
        }
        return UUID.randomUUID().toString();
    }


    public static synchronized void writePersistence(PersistenceInfo param) {
        writePersistence(param, Paths.get(PERSISTENCE_FILE_PATH));
    }


    @SneakyThrows
    public static synchronized void writePersistence(PersistenceInfo param,
                                                     Path resultPath) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(resultPath.toFile(), param);
    }


    @SneakyThrows
    public static PersistenceInfo readPersistence() {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(
                Paths.get(PERSISTENCE_FILE_PATH).toFile(),
                PersistenceInfo.class
        );
    }


}
